#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

/**
* Tests if the given contig exists in the reference.
*
* @author	Tao Yu
* @date	2011/3/5
*
* @param [in]	sub Contig.
* @param [in]	lstr	Reference.
* @param [in]	rstr	Reversed reference.
*/
void testExist(char *sub, char *lstr, char *rstr)
{
	char *p;
	if(p=strstr(lstr,sub)) {
		cout<<"YES"<<endl;
		cout<<"pos: "<<p-lstr<<endl;
	} else	if (p=strstr(rstr,sub)) {
		cout<<"YES (reverse)"<<endl;
		cout<<"pos: " <<p-rstr<<endl;
	} else {
		cout << "NO" <<endl;
	}
	cout<<"length: "<<strlen(sub)<<endl;
}

/**
*	Read reference from file.
*
* @author	Tao Yu
* @date	2011/3/4
*
* @param [in,out]	lstr	Reference string.
* @param [in,out]	rstr	Reversed reference.
* @param [in]			filename Reference file.
*/
void ReadReference(char * &lstr,char * &rstr, char* filename)
{
	ifstream ref(filename);
	if (!ref.is_open()) {
		cerr <<"Error while reading reference. (" << filename << ")" <<endl;
		exit(1);
	}
	cout <<"Begin reading reference." << endl;
	char buffer[1000000];
	// skip first line
	ref.getline(buffer, sizeof(buffer));
	int count = 0;
	char ch;
	while ((ch = ref.get()) != EOF)
	{
		if (ch != '\n' && ch !='\r')
		{
			++count;
			//if (count == 1 || count == 100000 || count == 100001)
			//{
			//	cout <<ch <<' ' <<int(ch) << ' ' << ref.eof() <<endl;
			//	cout <<"current pos " << ref.tellg() <<endl;
			//}
		}
	}
	lstr = new char[count+1];
	rstr = new char[count +1];
	lstr[count] = rstr[count] = '\0';
	int i=0;
	// have to clear, otherwise seekg may fail.
	ref.clear();
	ref.seekg(0);
	//cout << "current pos "  <<ref.tellg() <<endl;
	if (!ref.is_open()) {
		cerr <<"Error while reading reference. (" << filename << ")" <<endl;
		exit(1);
	}
	// skip first line
	ref.getline(buffer, sizeof(buffer));
	while ((ch = ref.get()) != EOF)
	{
		if (ch != '\n' && ch !='\r')
		{
			lstr[i++] = ch;
		}
	}
	//cout <<lstr <<endl;
	cout<<"Finished reading."<<endl;

	//reverse reference
	i=0;
	for (int j=count - 1; j>=0; --j)
	{
		switch(lstr[j])
		{
		case 'A':rstr[i]='T';break;
		case 'T':rstr[i]='A';break;
		case 'G':rstr[i]='C';break;
		case 'C':rstr[i]='G';break;
		default:cerr <<"The reference has wrong information. Pos: "<< j << ", Char: " <<lstr[j] <<endl;exit(0);
		}
		++i;
	}
	ref.close();
}

int main(int argc, char* argv[])
{
	char refFile[200];
	cout<<"Read file location: (../../examples/test_reference.fa)"<<endl;
	cin>>refFile;
	char contigFile[200];
	cout <<"Output file location: (../../examples/contig.fa)" <<endl;
	cin >> contigFile;

	char *lstr,*rstr;
	ReadReference(lstr, rstr, refFile);

	ifstream fin(contigFile);
	if (!fin.is_open()) {
		cerr << "Error while reading result. (" <<contigFile <<")" <<endl;
	}
	char buffer[1000000];
	if (!fin.eof())
	{
		fin.getline(buffer, 1000000);
		cout << buffer <<endl;
		fin.getline(buffer, 1000000);
		testExist(buffer,lstr,rstr);
	}
	fin.close();
}